package JUC.第02章_Future;

import util.OutColour;

import java.util.concurrent.*;

/**
 * CompletableFuture  继承的接口 有 Future和 CompletionStage
 */
public class D4_CompletionStageAPI对结果的处理 {
    public static void main(String[] args) {

        CompletableFuture<Integer> cf = CompletableFuture.supplyAsync(() -> {
            int result = ThreadLocalRandom.current().nextInt(10);//随机获取[0-9]
            try {TimeUnit.MILLISECONDS.sleep(2000);} catch (Exception e) {e.printStackTrace();}
            return result;
        });

        /**
         * cf.thenRun()
         * 任务A执行完执行B，并且B不需要A的结果
         * cf.thenAccept()   消费性接口
         * 任务A执行完执行B, B需要A的结果，但是任务B无返回值
         * cf.thenApply()  函数式接口
         * 任务A执行完执行B，B需要A的结果，同时任务B有返回值
         */
//        System.out.println("运算结果为:" + cf.join());
        cf.thenAccept(r -> {
            OutColour.out.printlnGreen("消费性接口:", r);
        });//没有返回值 是Consumer接口 消费性接口

        //Function 函数式接口  有入参和出参
        Integer thenApplyJoin = cf.thenApply(f -> {//中间出错   就会戛然而止  一般使用这个
            OutColour.out.printlnRed("thenApply第一步获取到：" + f);
            return f + 10;
        }).thenApply(f -> {
            OutColour.out.printlnRed("thenApply第二步获取到：" + f);
            int a = 1 / 0;
            return f + 100;
        }).thenApply(f -> {
            OutColour.out.printlnRed("thenApply第三步获取到：" + f);
            return f + 1000;
        }).whenComplete((v, e) -> {
            if (e == null) {
                OutColour.out.printlnRed("thenApply结果为：" + v);
            }
        }).exceptionally(e -> {
            OutColour.out.printlnRed("exceptionally：", e.getMessage());
            return null;
        }).join();
        OutColour.out.printlnRed("thenApply最终结果为：" + thenApplyJoin);

        System.out.println("----------------------------------------------");
        Integer handleJoin = cf.handle((f, e) -> {//中间出错   只终结其中一个
            OutColour.out.printlnYellow("handle第一步获取到：", f);
            int a = 10 / 0; //此步奏出错了
            return f + 10;
        }).handle((f, e) -> {
            OutColour.out.printlnYellow("handle第二步获取到：", f);
            return f + 100;
        }).handle((f, e) -> {
            f = f == null ? 666 : f;//此步骤依旧执行 但是前面的值的变化都相当于白跑了
            OutColour.out.printlnYellow("handle第三步获取到：", f);
            return f + 1000;
        }).whenComplete((v, e) -> {//只要最后一步 没抛错  就有值
            if (e == null) {
                OutColour.out.printlnYellow("handle结果为：" + v);
            } else {
                OutColour.out.printlnYellow("异常handle结果为：" + v);//null
            }
        }).exceptionally(e -> {//只要最后一步 没抛错  就不会执行
//            e.printStackTrace();
            OutColour.out.printlnYellow("exceptionally：", e.getMessage());
            return null;
        }).join();
        OutColour.out.printlnYellow("handle最终结果为：" , handleJoin);


        OutColour.out.println("运算结果为：" + cf.join());
    }
}
